/*
  FileName : UartData.c
  Description:
  Created on 2008.11.28 by ZZP.

  Revision History:

*/

#include "DSP281x_Device.h"
#include "GPS_Location_Handle.h"
#include "CirGpsCommand.h"
#include "GPS_SatelliteData.h"

const Uns RX_SCIA_STR[] = {'R', 'x', ' ', 'f', 'r', 'o', 'm', ' ', ' ', 
                       'S', 'c', 'i', 'A', ':', 0x0D, 0x0A};
const Uns RX_SCIB_STR[] = {'R', 'x', ' ', 'f', 'r', 'o', 'm', ' ', ' ', 
                       'S', 'c', 'i', 'B', ':', 0x0D, 0x0A};
const Uns RX_GSMR_STR[] = {'R', 'x', ' ', 'f', 'r', 'o', 'm', ' ', ' ', 
                       'G', 's', 'm', 'r', ':', 0x0D, 0x0A};
const Uns RX_YS_STR[]   = {'R', 'x', ' ', 'f', 'r', 'o', 'm', ' ', ' ', 
                       'Y', 's', ' ', ' ', ':', 0x0D, 0x0A};
const Uns RX_MOB_STR[]  = {'R', 'x', ' ', 'f', 'r', 'o', 'm', ' ', ' ', 
                       'M', 'o', 'b', ' ', ':', 0x0D, 0x0A};
const Uns RX_PUB_STR[]  = {'R', 'x', ' ', 'f', 'r', 'o', 'm', ' ', ' ', 
                       'P', 'u', 'b', ' ', ':', 0x0D, 0x0A};

//////////////////////////////////////////////////////////
//  UART Tx variables:
//////////////////////////////////////////////////////////
UART_PORT_INFO GpsPortInfo;
UART_PORT_INFO YSPortInfo;
UART_PORT_INFO MobPortInfo;
UART_PORT_INFO GsmrPortInfo;
UART_PORT_INFO PubPortInfo;

//----------------------------------------
#ifdef __cplusplus 
#pragma DATA_SECTION("UserDataFile") 
#else 
#pragma DATA_SECTION(Gps_TxBuf,"UserDataFile");
#endif 
Uns Gps_TxBuf[Gps_TxBufCnt_Mask + 1][Gps_OneTxBuf_Len];

//----------------------------------------
#ifdef __cplusplus 
#pragma DATA_SECTION("UserDataFile") 
#else 
#pragma DATA_SECTION(YS_TxBuf,"UserDataFile");
#endif 
Uns YS_TxBuf[YS_TxBufCnt_Mask + 1][YS_OneTxBuf_Len];

//----------------------------------------
#ifdef __cplusplus 
#pragma DATA_SECTION("UserDataFile") 
#else 
#pragma DATA_SECTION(Mob_TxBuf,"UserDataFile");
#endif 
Uns Mob_TxBuf[Mob_TxBufCnt_Mask + 1][Mob_OneTxBuf_Len];

//SciA
//----------------------------------------
#ifdef __cplusplus 
#pragma DATA_SECTION("UserDataFile") 
#else 
#pragma DATA_SECTION(Gsmr_TxBuf,"UserDataFile");
#endif 
Uns Gsmr_TxBuf[Gsmr_TxBufCnt_Mask + 1][Gsmr_OneTxBuf_Len];

//SciB
//----------------------------------------
#ifdef __cplusplus 
#pragma DATA_SECTION("UserDataFile") 
#else 
#pragma DATA_SECTION(Pub_TxBuf,"UserDataFile");
#endif 
Uns Pub_TxBuf[Pub_TxBufCnt_Mask + 1][Pub_OneTxBuf_Len];



//////////////////////////////////////////////////////////
//  UART Rx variables:
//////////////////////////////////////////////////////////
UART_RX_INFO GpsRxInfo;
UART_RX_INFO YSRxInfo;
UART_RX_INFO MobRxInfo;
UART_RX_INFO GsmrRxInfo;
UART_RX_INFO PubRxInfo;

//----------------------------------------
#ifdef __cplusplus 
#pragma DATA_SECTION("UserDataFile") 
#else 
#pragma DATA_SECTION(Gps_RxBuf,"UserDataFile");
#endif
Uns Gps_RxBuf[Gps_RxBufCnt_Mask + 1][Gps_OneRxBuf_Len];

//----------------------------------------
#ifdef __cplusplus 
#pragma DATA_SECTION("UserDataFile") 
#else 
#pragma DATA_SECTION(YS_RxBuf,"UserDataFile");
#endif 
Uns YS_RxBuf[YS_RxBufCnt_Mask + 1][YS_OneRxBuf_Len];

//----------------------------------------
#ifdef __cplusplus 
#pragma DATA_SECTION("UserDataFile") 
#else 
#pragma DATA_SECTION(Mob_RxBuf,"UserDataFile");
#endif 
Uns Mob_RxBuf[Mob_RxBufCnt_Mask + 1][Mob_OneRxBuf_Len]; 

//----------------------------------------
#ifdef __cplusplus 
#pragma DATA_SECTION("UserDataFile") 
#else 
#pragma DATA_SECTION(Gsmr_RxBuf,"UserDataFile");
#endif 
Uns Gsmr_RxBuf[Gsmr_RxBufCnt_Mask + 1][Gsmr_OneRxBuf_Len]; 

//----------------------------------------
#ifdef __cplusplus 
#pragma DATA_SECTION("UserDataFile") 
#else 
#pragma DATA_SECTION(Pub_RxBuf,"UserDataFile");
#endif 
Uns Pub_RxBuf[Pub_RxBufCnt_Mask + 1][Pub_OneRxBuf_Len]; 


/////////////////////////////////////////////////////////////////////
// Local variables:
/////////////////////////////////////////////////////////////////////
//----------------------------------------
#ifdef __cplusplus 
#pragma DATA_SECTION("UserDataFile") 
#else 
#pragma DATA_SECTION(Gps_tmpBuf,"UserDataFile");
#endif 
Uns Gps_tmpBuf[256]; 

//----------------------------------------
#ifdef __cplusplus 
#pragma DATA_SECTION("UserDataFile") 
#else 
#pragma DATA_SECTION(Gsmr_tmpBuf,"UserDataFile");
#endif 
Uns Gsmr_tmpBuf[256]; 
/*
//----------------------------------------
#ifdef __cplusplus 
#pragma DATA_SECTION("UserDataFile") 
#else 
#pragma DATA_SECTION(Pub_tmpBuf,"UserDataFile");
#endif 
Uns Pub_tmpBuf[256]; 
*/

//----------------------------------------
#ifdef __cplusplus 
#pragma DATA_SECTION("UserDataFile") 
#else 
#pragma DATA_SECTION(tmpTxBuf,"UserDataFile");
#endif 
Uns tmpTxBuf[1024]; 


extern volatile Uns Tm5Seconds;
extern DATA_BASE_INFO DataBase;

/**************************************************************************************
***************************************************************************************
               Functions
***************************************************************************************
***************************************************************************************/
void InitUartVars(void)
{
  //////////////////////////////////////////////////////////
  //  UART Tx variables:
  //////////////////////////////////////////////////////////
  //Gps:
  GpsPortInfo.Port = GPS_PORT;
  GpsPortInfo.BufBaseAddr = &Gps_TxBuf[0][0];
  GpsPortInfo.BufCntMask = Gps_TxBufCnt_Mask;
  GpsPortInfo.OneBufLen = Gps_OneTxBuf_Len;
  GpsPortInfo.Index = 0;
  GpsPortInfo.HandleIndex = 0;
  GpsPortInfo.RemainLen = 0;
  GpsPortInfo.TxFlag = 0;
  GpsPortInfo.TxTm = 0;
  GpsPortInfo.TxPtr = GpsPortInfo.BufBaseAddr;
  //YS Data:
  YSPortInfo.Port = YS_PORT;
  YSPortInfo.BufBaseAddr = &YS_TxBuf[0][0];
  YSPortInfo.BufCntMask = YS_TxBufCnt_Mask;
  YSPortInfo.OneBufLen = YS_OneTxBuf_Len;
  YSPortInfo.Index = 0;
  YSPortInfo.HandleIndex = 0;
  YSPortInfo.RemainLen = 0;
  YSPortInfo.TxFlag = 0;
  YSPortInfo.TxTm = 0;
  YSPortInfo.TxPtr = YSPortInfo.BufBaseAddr;
  //Mobile :
  MobPortInfo.Port = MOB_PORT;
  MobPortInfo.BufBaseAddr = &Mob_TxBuf[0][0];
  MobPortInfo.BufCntMask = Mob_TxBufCnt_Mask;
  MobPortInfo.OneBufLen = Mob_OneTxBuf_Len;
  MobPortInfo.Index = 0;
  MobPortInfo.HandleIndex = 0;
  MobPortInfo.RemainLen = 0;
  MobPortInfo.TxFlag = 0;
  MobPortInfo.TxTm = 0;
  MobPortInfo.TxPtr = MobPortInfo.BufBaseAddr;
  //SciA(Gsmr):
  GsmrPortInfo.Port = SCI_A_PORT;
  GsmrPortInfo.BufBaseAddr = &Gsmr_TxBuf[0][0];
  GsmrPortInfo.BufCntMask = Gsmr_TxBufCnt_Mask;
  GsmrPortInfo.OneBufLen = Gsmr_OneTxBuf_Len;
  GsmrPortInfo.Index = 0;
  GsmrPortInfo.HandleIndex = 0;
  GsmrPortInfo.RemainLen = 0;
  GsmrPortInfo.TxFlag = 0;
  GsmrPortInfo.TxTm = 0;
  GsmrPortInfo.TxPtr = GsmrPortInfo.BufBaseAddr;
  //SciB(Public data):
  PubPortInfo.Port = SCI_B_PORT;
  PubPortInfo.BufBaseAddr = &Pub_TxBuf[0][0];
  PubPortInfo.BufCntMask = Pub_TxBufCnt_Mask;
  PubPortInfo.OneBufLen = Pub_OneTxBuf_Len;
  PubPortInfo.Index = 0;
  PubPortInfo.HandleIndex = 0;
  PubPortInfo.RemainLen = 0;
  PubPortInfo.TxFlag = 0;
  PubPortInfo.TxTm = 0;
  PubPortInfo.TxPtr = PubPortInfo.BufBaseAddr;

  //////////////////////////////////////////////////////////
  //  UART Rx variables:
  //////////////////////////////////////////////////////////
  //YS Data:
  YSRxInfo.Port = YS_PORT;
  YSRxInfo.DestBaseAddr = &YS_RxBuf[0][0];
  YSRxInfo.BufCntMask = YS_RxBufCnt_Mask;
  YSRxInfo.OneBufLen = YS_OneRxBuf_Len;
  YSRxInfo.DLE = 0;
  YSRxInfo.Cnt = 0;
  YSRxInfo.Index = 0;
  YSRxInfo.HandleIndex = 0;
  YSRxInfo.StartF = 0;
  YSRxInfo.RxTm = 0;
  YSRxInfo.RxFlag = 0;
  //Mob data:
  MobRxInfo.Port = MOB_PORT;
  MobRxInfo.DestBaseAddr = &Mob_RxBuf[0][0];
  MobRxInfo.BufCntMask = Mob_RxBufCnt_Mask;
  MobRxInfo.OneBufLen = Mob_OneRxBuf_Len;
  MobRxInfo.DLE = 0;
  MobRxInfo.Cnt = 0;
  MobRxInfo.Index = 0;
  MobRxInfo.HandleIndex = 0;
  MobRxInfo.StartF = 0;
  MobRxInfo.RxTm = 0;
  MobRxInfo.RxFlag = 0;
  //Gsmr data:
  GsmrRxInfo.Port = SCI_A_PORT;
  GsmrRxInfo.DestBaseAddr = &Gsmr_RxBuf[0][0];
  GsmrRxInfo.BufCntMask = Gsmr_RxBufCnt_Mask;
  GsmrRxInfo.OneBufLen = Gsmr_OneRxBuf_Len;
  GsmrRxInfo.DLE = 0;
  GsmrRxInfo.Cnt = 0;
  GsmrRxInfo.Index = 0;
  GsmrRxInfo.HandleIndex = 0;
  GsmrRxInfo.StartF = 0;
  GsmrRxInfo.RxTm = 0;
  GsmrRxInfo.RxFlag = 0;
  //Pub data:
  PubRxInfo.Port = SCI_B_PORT;
  PubRxInfo.DestBaseAddr = &Pub_RxBuf[0][0];
  PubRxInfo.BufCntMask = Pub_RxBufCnt_Mask;
  PubRxInfo.OneBufLen = Pub_OneRxBuf_Len;
  PubRxInfo.DLE = 0;
  PubRxInfo.Cnt = 0;
  PubRxInfo.Index = 0;
  PubRxInfo.HandleIndex = 0;
  PubRxInfo.StartF = 0;
  PubRxInfo.RxTm = 0;
  PubRxInfo.RxFlag = 0;
}

void TaxDataHandler(void)
{
  switch (MyInfo.RxTaxHead)
  {
    case TAX_HEAD_38:
	  Tax38Handler();
	  break;
	case TAX_HEAD_39:
	  Tax39Handler();
	  break;
	default:
	  break;
  }
  MyInfo.RxTaxHead = 0;
}

void Tax38Handler(void)
{
  MyInfo.Tax38Ready = 1;
}

void Tax39Handler(void)
{
  Uns temp, tmpBuf[2];

  tmpBuf[0] = Tax39Buf[3] + (Tax39Buf[4] << 8);   //秒、分、时、日、月
  tmpBuf[1] = Tax39Buf[5] + (Tax39Buf[6] << 8); //7位TAX协议：年0~63
  temp = CheckTimeValid(TIME_SRC_TAX2, tmpBuf);
  if (temp)
  {
    if (Tax39Buf[23] & 0x02)//补机
      MyInfo.BenwuF = 0;
    else
      MyInfo.BenwuF = 1;
	
    MyInfo.Tax39Ready = 1;
	//将数据发往GSMR:数据头定义？
	//PrepareUartData((UART_PORT_INFO *)&PubPortInfo, (UART_PORT_INFO *)&GsmrPortInfo,
	//                   Tax39Buf, 40, 8, 0);
  }
}

Uns CheckUartData(Uns *Data)
{
  volatile Uns RxLen, Len, /*Src,*/ SrcLen, Dst, DstLen, /*Type,*/ Crc, CrcCalc;

  RxLen = Data[0];
  //LSB first
  //Len = Data[1] + (Data[2] << 8);
  //MSB first
  Len = Data[2] + (Data[1] << 8);

  //Src = Data[3];
  SrcLen = Data[4];
  Dst = Data[5];
  DstLen = Data[6];
  //Type = Data[7];
  //Cmd = Data[8];
  if (RxLen != Len + 2)
    return (0);
  if ((Len < 8) || (Len > 255))
    return (0);
  if (SrcLen != 0)
    return (0);
  if (DstLen != 0)
    return (0);
  if (Dst != 0x06)//GPS
    return (0);
  CrcCalc = Calc_CRCByte(Data + 1, Len);
  //MSB First
  Crc = (Data[1 + Len] << 8) + Data[2 + Len];
  if (CrcCalc != Crc)
    return (0);
  return (1);
}


void CommandHandler(UART_PORT_INFO *Port, Uns *Data, Uns Cmd, Uns Src, Uns DataLen)
{
	Uns temp, Buf[40];

	Buf[0] = 0;		//Length MSB
	Buf[1] = 0;		//Length LSB
	Buf[2] = 0x06;	//source ID
	Buf[3] = 0x00;
	Buf[4] = 0x80;	//Destination ID
	Buf[5] = 0x00;
	Buf[6] = 0x02;	//CMD type
	Buf[7] = Cmd;	//CMD
	switch (Cmd)
	{

	case Rx_Cmd_MMI_AskRegion:
		MyInfo.MMI_LineAskingFlag = 1;
		if (MyInfo.MMI_SelAbs)
		{
	 	  MyInfo.MMI_SelAbs = 3;
		}
		break;

	case Rx_Cmd_MMI_AskUpDown:
		MyInfo.MMI_AskUpDownF = 1;
		break;

	case Rx_Cmd_MMI_SetUpDown:		//0x4B added by WFL at 2015-03-19
		MyInfo.MMI_UpDown = *Data;
		break;

	case Rx_Cmd_StartSimulate:		//0xA1 enter GPS simulation mode
		if (MyInfo.WorkSts == WORK_STATUS_NORMAL)
			MyInfo.SimulateSts = 1;
		break;

    case Rx_Cmd_SimulateData:		//0xA2, GPS模拟数据
	  Tm5Seconds = 0;
	  if ((MyInfo.GpsDataHandled == 1) && (MyInfo.WorkSts == WORK_STATUS_GPS_SIMULATE))
	  {
	    memcpy(YSGpsBuf, Data, DataLen);
		MyInfo.SimulateSts = 2;
		MyInfo.GpsDataLen = DataLen;	//此处设置数据长度以便周期函数能启动相关任务
	  }
	  else
	  {
	    Buf[7] |= 0x10;
	  }
	  Buf[1] = 8;
	  PrepareUartData(Port, NULL, Buf, 10, 8, 0);	//此为8位数据
	  break;

    case Rx_Cmd_ExitSimulate://   0xA3, 退出GPS模拟
	  if (MyInfo.WorkSts == WORK_STATUS_GPS_SIMULATE)
	  {
	    MyInfo.SimulateSts = 3;
	    if (MyInfo.MMI_SelAbs)
	    {
	    	MyInfo.MMI_SelAbs = 3;
	    }
	  }
	  break;

	case Rx_Cmd_MMI_SetRoad:		//0x4E --MMI向卫星定位单元发送线路设置信息
	case Rx_Cmd_MMI_SetRoad_Abs:	//0x4D --强制设置线路
	  memcpy(&(Road_Select.MMI_Mode), Data, 30);
	  MyInfo.MMI_RdValid = 1;

	  //车次号数字部分尾数：位于三字节数字的第一个
	  //此处应答：
	  Buf[0] = 0;
	  Buf[1] = 10;
	  Buf[4] = Src;		//接收源地址：发送目的地址
	  Buf[6] = 0x03;	//业务类型：于收到的一致
	  Buf[7] = 0x01;	//CMD

	  Buf[8] = Cmd;
	  Buf[9] = Data[0];
	  PrepareUartData(Port, NULL, Buf, 12, 8, 0);

	  if (Cmd == Rx_Cmd_MMI_SetRoad_Abs)
	  	  MyInfo.MMI_SelAbs = 1;
	   else if (MyInfo.MMI_SelAbs)
	   {
	  	  MyInfo.MMI_SelAbs = 3;
	   }
	  break;

    case Rx_Cmd_Inquiry://        0xA4
	  switch (Data[0])
	  {
	  case Cmd_Inquiry_BusySts://  0x00
		  Buf[1] = 8 + 2;
		  Buf[8] = 0x00;//类型：工作状态
		  if (MyInfo.RoadLocked == ROAD_LOCKED)
		    Buf[9] = 1;
		  else
		    Buf[9] = 0;
		  PrepareUartData(Port, NULL, Buf, 12, 8, 0);
		  break;
	  case Cmd_Inquiry_DataBase:// 0x01
		  Buf[1] = 8 + 20;
		  Buf[8] = 0x01;
		  Buf[9] = 'V';
		  Buf[10] = '2';
		  Buf[11] = '.';
		  Buf[12] = '1';
		  Buf[13] = '.';
		  Buf[14] = ((MyInfo.SoftVer >> 4) & 0x0f) + 0x30;
		  Buf[15] = (MyInfo.SoftVer & 0x0f) + 0x30;
		  Buf[16] = '-';
		  temp = DataBase.Time.Year % 100;
		  Buf[17] = (temp / 10) + 0x30;
		  Buf[18] = (temp % 10) + 0x30;
		  Buf[19] = '/';
		  temp = DataBase.Time.Month;
		  Buf[20] = temp / 10 + 0x30;
		  Buf[21] = (temp % 10)  + 0x30;
		  Buf[22] = '/';
		  temp = DataBase.Time.Date;
		  Buf[23] = temp / 10  + 0x30;
		  Buf[24] = (temp % 10) + 0x30;
		  Buf[25] = ' ';
		  Buf[26] = '0';
		  Buf[27] = '8';
		  PrepareUartData(Port, NULL, Buf, 30, 8, 0);
		  break;
	    case Cmd_Inquiry_Clk://      0x02
		  Buf[1] = 8 + 9;
		  Buf[8] = 0x02;
		  Buf[9] = AllTime.SysTime.Second;
		  Buf[10] = AllTime.SysTime.Minute;
		  Buf[11] = AllTime.SysTime.Hour;
		  Buf[12] = AllTime.SysTime.Date;
		  Buf[13] = AllTime.SysTime.Month;
		  Buf[14] = AllTime.SysTime.Year & 0xFF;
		  Buf[15] = 0;//AllTime.SysTime.Year >> 8;
		  Buf[16] = 0;
		  PrepareUartData(Port, NULL, Buf, 19, 8, 0);
		  break;
		case Cmd_Inquiry_SoftVer:
		  Buf[1] = 8 + 20;
		  Buf[8] = 0x03;
		  Buf[9] = 'V';
		  Buf[10] = '2';
		  Buf[11] = '.';
		  Buf[12] = '1';
		  Buf[13] = '.';
		  Buf[14] = ((MyInfo.SoftVer >> 4) & 0x0f) + 0x30;
		  Buf[15] = (MyInfo.SoftVer & 0x0f) + 0x30;
		  Buf[16] = '-';
		  Buf[17] = ((MyInfo.SoftDate >> 20) & 0x0F) + 0x30;
		  Buf[18] = ((MyInfo.SoftDate >> 16) & 0x0F) + 0x30;
		  Buf[19] = '/';
		  Buf[20] = ((MyInfo.SoftDate >> 12) & 0x0F) + 0x30;
		  Buf[21] = ((MyInfo.SoftDate >> 8) & 0x0F)  + 0x30;
		  Buf[22] = '/';
		  Buf[23] = ((MyInfo.SoftDate >> 4) & 0x0F)  + 0x30;
		  Buf[24] = (MyInfo.SoftDate & 0x0F) + 0x30;
		  Buf[25] = ' ';
		  Buf[26] = '0';
		  Buf[27] = '8';
		  PrepareUartData(Port, NULL, Buf, 30, 8, 0);
		  break;
		default:
		  break;
	  }
	  break;

    case Rx_Cmd_CalibrateClk://   0xA5
	  break;

	case Rx_Cmd_MMI_Ack_SelRoad://0x41
	  break;
    default:
      break;
  }
}

///#pragma CODE_SECTION(GsmrRxDataHandler, "FuncsMap2H0SARam")
void GsmrRxDataHandler(void)
{
  Uns Cmd, Len, Src;

  if (GsmrRxInfo.HandleIndex != GsmrRxInfo.Index)
  {
    if (CheckUartData(Gsmr_RxBuf[GsmrRxInfo.HandleIndex]))
	{
	  Cmd = Gsmr_RxBuf[GsmrRxInfo.HandleIndex][8];
	  Len = Gsmr_RxBuf[GsmrRxInfo.HandleIndex][0] - 8 - 2;
	  Src = Gsmr_RxBuf[GsmrRxInfo.HandleIndex][3];
	  CommandHandler((UART_PORT_INFO *)&GsmrPortInfo, Gsmr_RxBuf[GsmrRxInfo.HandleIndex] + 9, Cmd, Src, Len);
	}
	IncIndex(&GsmrRxInfo.HandleIndex, GsmrRxInfo.BufCntMask);
  }
}

///#pragma CODE_SECTION(PubRxDataHandler, "FuncsMap2H0SARam")
void PubRxDataHandler(void)
{
  Uns Cmd, Len, Src;

  if (PubRxInfo.HandleIndex != PubRxInfo.Index)
  {
    if (CheckUartData(Pub_RxBuf[PubRxInfo.HandleIndex]))
	{
	  Cmd = Pub_RxBuf[PubRxInfo.HandleIndex][8];
	  Len = Pub_RxBuf[PubRxInfo.HandleIndex][0] - 8 - 2;
	  Src = Pub_RxBuf[PubRxInfo.HandleIndex][3];
	  CommandHandler((UART_PORT_INFO *)&PubPortInfo, Pub_RxBuf[PubRxInfo.HandleIndex] + 9, Cmd, Src, Len);
	}
    IncIndex(&PubRxInfo.HandleIndex, PubRxInfo.BufCntMask);
  }
}

///#pragma CODE_SECTION(YSRxDataHandler, "FuncsMap2H0SARam")
void YSRxDataHandler(void)
{
  if (YSRxInfo.HandleIndex != YSRxInfo.Index)
  {

    IncIndex(&YSRxInfo.HandleIndex, YSRxInfo.BufCntMask);
  }
}

void MobRxDataHandler(void)
{
  if (MobRxInfo.HandleIndex != MobRxInfo.Index)
  {

    IncIndex(&MobRxInfo.HandleIndex, MobRxInfo.BufCntMask);
  }
}
/*
 * Data: is the address of FrameLength, just behind frame head 1002H.
 * TotBytes: is the total number of the whole data frame except 1002H and 1003H.
 * DataBits: to tell the width of Data.(8 bit or 16 bit)
 * the CRC of data frame calculate here.
 */
///#pragma CODE_SECTION(PrepareUartData, "FuncsMap2H0SARam")
void PrepareUartData(UART_PORT_INFO *Port, UART_PORT_INFO *Port2, 
                     Uns *Data, Uns TotBytes, Uns DataBits, Uns Dbg)
{
  Uns i, j, n, Len, DataLen, Crc, temp, *P, *P2, *P3;

  P = Port->BufBaseAddr + Port->Index * Port->OneBufLen;
  Len = TotBytes;
  //高位在前
  //temp = Data[0];
  //Data[0] = (temp << 8) + (temp >> 8);

  //Data is the address of FrameLength, just behind frame head 1002H.
  Crc = Calc_CRCWord(Data, DataBits, Len - 2);
  switch (Dbg)
  {
    case DBG_RX_SCI_A://   1
	  n = 16;
	  P3 = (void *)&RX_SCIA_STR;
	  break;
	case DBG_RX_SCI_B://   2
	  n = 16;
	  P3 = (void *)&RX_SCIB_STR;
	  break;
	case DBG_RX_GSMR://    3
	  n = 16;
	  P3 = (void *)&RX_GSMR_STR;
	  break;
	case DBG_RX_YS://      4
	  n = 16;
	  P3 = (void *)&RX_YS_STR;
	  break;
	case DBG_RX_MOB://     5
	  n = 16;
	  P3 = (void *)&RX_MOB_STR;
	  break;
	case DBG_RX_PUB://     6
	  n = 16;
	  P3 = (void *)&RX_PUB_STR;
	  break;
	default:
	  n = 0;
	  break;
  }
  //p[0] is used to put the numbers of data needed to send by UART.
  if (n)
    memcpy(P + 1, P3, 16);
  P[n + 1] = 0x10;	//frame head
  P[n + 2] = 0x02;	//frame head
  j = n + 3;
  if (DataBits == 16)
  {
    DataLen = (Len - 2) >> 1;//-2:dose not include CRC
    for (i = 0; i < DataLen; i++)
	{
	  temp = *Data++;
	  P[j++] = temp & 0xFF;
	  if ((temp & 0xFF) == 0x10)
	    P[j++] = 0x10;
	  P[j++] = temp >> 8;
	  if ((temp >> 8) == 0x10)
	    P[j++] = 0x10;
	}
	if (Len & 0x01)//
	{
	  P[j++] = *Data & 0xFF;
	  if((*Data & 0xFF)==0x10)
		  P[j++] = 0x10;
	}
  }
  else
  {
    for (i = 0; i < Len - 2; i++)
	{
	  temp = *Data++;
	  P[j++] = temp & 0xFF;
	  if ((temp & 0xFF) == 0x10)
	    P[j++] = 0x10;
	}
  }
  //Crc : MSB first
  P[j++] = Crc >> 8;
  if ((Crc >> 8) == 0x10)
    P[j++] = 0x10;
  P[j++] = Crc & 0xFF;
  if ((Crc & 0xFF) == 0x10)
    P[j++] = 0x10;
  P[j++] = 0x10;
  P[j] = 0x03;
  if (n)
  {
    j++;
	P[j++] = 0x0D;
	P[j] = 0x0A;
  }
  P[0] = j;

  if (Port2 != NULL)
  {
    P2 = Port2->BufBaseAddr + Port2->Index * Port2->OneBufLen;
	memcpy(P2, P, j + 1);
	IncIndex(&Port2->Index, Port2->BufCntMask);
  }
  IncIndex(&Port->Index, Port->BufCntMask);
}







